package com.uobgroup.ews.uam.core.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.uobgroup.ews.uam.core.common.SecurityGroupUtils;
import com.uobgroup.ews.uam.core.dao.ReferenceDao;
import com.uobgroup.ews.uam.core.domain.Reference;
import com.uobgroup.ews.uam.core.domain.ReferenceType;
import com.uobgroup.ews.uam.core.domain.Segment;
import com.uobgroup.ews.uam.core.enums.ScopeType;

@Service
@Transactional
public class ReferenceServiceImpl implements ReferenceService {

   @Autowired
   private ReferenceDao referenceDao;
   
   @Autowired
   private ReferenceTypeService referenceTypeService;

   public long countAllReferences() {
      return referenceDao.count();
   }

   public void deleteReference(Reference reference) {
      referenceDao.delete(reference);
   }

   public Reference findReference(Long id) {
      return referenceDao.findOne(id);
   }

   public List<Reference> findAllReferences() {
      return referenceDao.findAll();
   }
   
   public List<Reference> findAllReferencesThatHasNoSegment() {
      ReferenceType segmentType = referenceTypeService.findReferenceTypeByCode("SEGMENT");
      return referenceDao.findAllReferencesThatHasNoSegment(segmentType);
   }

   public List<Reference> findReferenceEntries(int firstResult, int maxResults) {
      return referenceDao.findAll(firstResult, maxResults);
   }

   public void saveReference(Reference reference) {
      referenceDao.save(reference);
   }

   public Reference updateReference(Reference reference) {
      return referenceDao.update(reference);
   }
   
   public List<Reference> findAllProcessingCenters() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("PROCESSING_CENTER");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.PROCESSING_CENTER);
   }
   
   public List<Reference> findAllDepartments() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("DEPARTMENT");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.DEPARTMENT);
   }

   public List<Reference> findAllCountrys() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("COUNTRY");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.COUNTRY);
   }

   public List<Reference> findAllDocumentTypes() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("DOCUMENT_TYPE");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.DOCUMENT_TYPE);
   }

   public List<Reference> findAllProductTypes() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("PRODUCT_TYPE");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.PRODUCT_TYPE);
   }

   public List<Reference> findAllTransactionTypes() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("TRANSACTION_TYPE");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.TRANSACTION_TYPE);
   }
   
   public List<Reference> findAllUserLocations() {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("LOCATION");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.LOCATION);
   }
   
   public List<Reference> findAllRoleType()
   {
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("ROLE_TYPE");
      return referenceDao.findAllReferencesByType(referenceType);
      //return referenceDao.findReferencesByType(ReferenceType.ROLE_TYPE);
   }
   
   public Reference findFirstReferenceRoleType()
   {
      /*List<Reference> listRef = referenceDao.findReferencesByType(ReferenceType.ROLE_TYPE);*/
      ReferenceType referenceType = referenceTypeService.findReferenceTypeByCode("ROLE_TYPE");
      List<Reference> listRef = referenceDao.findAllReferencesByType(referenceType);
      if(listRef.size() == 0)
         return null;         
      return listRef.get(0);
   }
   
   public void saveSegment(Segment segment) {
      /*Reference reference = segment.getSegmentReference();
      reference.setSegment(segment);
      referenceDao.save(reference);*/
      segment.setSecurityGroup(SecurityGroupUtils.getSecurityGroup(segment));
      referenceDao.addSegment(segment);
   }

   public Segment findSegment(Long id) {
      return referenceDao.findSegment(id);
   }

   @Override
   public List<Segment> findSegmentEntries(int firstResult, int sizeNo) {
      return referenceDao.findSegmentEntries(firstResult, sizeNo);
   }

   @Override
   public float countSegments() {
      return referenceDao.countSegments();
   }

   @Override
   public List<Segment> findAllSegments() {
      return referenceDao.findAllSegments();
   }

   @Override
   public void updateSegment(Segment segment) {
      this.saveSegment(segment);
   }

   @Override
   public void remove(Segment segment) {
      referenceDao.removeSegment(segment);
   }

   @Override
   public List<Reference> findSegmentReferenceByName(String name) {
      return referenceDao.findSegmentReferencesByName(name);
   }
   /**
    * DONGN
    */

   @Override
   public long countReferencesByType(ReferenceType referenceType) {
      return referenceDao.countReferencesByType(referenceType);
   }

   @Override
   public List<Reference> findReferencesByType(ReferenceType referenceType, int firstResult, int maxResults) {
      return referenceDao.findReferencesByType(referenceType, firstResult, maxResults);
   }
   
   @Override
   public Reference findReferenceByName(String name) {
      return referenceDao.findReferenceByName(name);
   }
   
   @Override
   public Reference findReferenceByCode(String code) {
      return referenceDao.findReferenceByCode(code);
   }
   
   @Override
   public List<Reference> findReferencesThatHasSecurityScope(int firstResult, int maxResults) {
      return referenceDao.findReferencesByReferenceTypeScope(ScopeType.SECURITY, firstResult, maxResults);
   }

   @Override
   public List<Reference> findReferencesThatHasApplicationScope(int firstResult, int maxResults) {
      return referenceDao.findReferencesByReferenceTypeScope(ScopeType.APPLICATION, firstResult, maxResults);
   }

   @Override
   public long countReferencesBySecurityScope() {
      return referenceDao.countReferencesByReferenceTypeScope(ScopeType.SECURITY);
   }

   @Override
   public long countReferencesByApplicationScope() {
      return referenceDao.countReferencesByReferenceTypeScope(ScopeType.APPLICATION);
   }

   @Override
   public Reference findReferenceByIdAndSecurityScope(Long id) {
      return referenceDao.findReferenceByIdAndScope(id, ScopeType.SECURITY);
   }

   @Override
   public Reference findReferenceByIdAndApplicationScope(Long id) {
      return referenceDao.findReferenceByIdAndScope(id, ScopeType.APPLICATION);
   }

   @Override
   public Reference findReferenceThatHasNameAndNotHasId(String name, Long id) {
      return referenceDao.findReferenceThatHasNameAndNotHasId(name, id);
   }
   
   @Override
   public Reference findReferenceThatHasCodeAndNotHasId(String code, Long id) {
      return referenceDao.findReferenceThatHasCodeAndNotHasId(code, id);
   }

   @Override
   public List<ReferenceType> findReferenceTypesThatHasReferencesByApplicationScope() {
      return referenceDao.findReferenceTypesThatHasReferencesByScope(ScopeType.APPLICATION);
   }

   @Override
   public List<ReferenceType> findReferenceTypesThatHasReferencesBySecurityScope() {
      return referenceDao.findReferenceTypesThatHasReferencesByScope(ScopeType.SECURITY);
   }
   
   @Override
   public Reference findReferencesByType(ReferenceType referenceType) {
      return referenceDao.findReferencesByType(referenceType);
   }
   
   @Override
   public long countSegmentsThatHasSegmentReference(Reference segment) {
      return referenceDao.countSegmentsThatHasSegmentReference(segment);
   }
   /**
    * END DONGN
    */
}
